const fs = require('fs-extra')
const { createPluginContainer } = require('../server/pluginContainer')
const resolvePlugin = require('../plugins/resolve')
const { normalizePath } = require('../utils')

const htmlTypesRE = /\.html$/
const scriptModuleRE = /<script type="module" src\="(.+?)"><\/script>/

/**
 *  esbuildc插件 获取扫描插件的工厂方法
 * @param {*} config  配置对象
 * @param {*} depImports 将用来存放导入的模块
 * @returns
 */
async function getScanPlugin(config, depImports) {
  const container = await createPluginContainer({
    plugins: [resolvePlugin(config)],
    root: config.root,
  })

  // 把任意路径转成绝对路径，
  const resolve = async (path, importer) => {
    return await container.resolveId(path, importer)
  }

  return {
    name: 'scan', // 依赖扫描插件
    setup(build) {
      //  入口文件是 html 找到index.html的真实路径
      build.onResolve({ filter: htmlTypesRE }, async ({ path, importer }) => {
        // 把任意路径转成绝对路径，
        // path 可能是相对 ./index.html
        // 绝对路径 c::/Users/xxx/xxx/index.html
        // 第三方 index.html
        const resolved = await resolve(path, importer)
        if (resolved) {
          return {
            path: resolved.id || resolved,
            namespace: 'html',
          }
        }
      })

      build.onResolve({ filter: /.*/ }, async ({ path, importer }) => {
        // 把任意路径转成绝对路径，
        // const resolve = path
        const resolved = await resolve(path, importer)
        if (resolved) {
          const id = resolved.id || resolved // 此模块的绝对路径
          if (id.includes('node_modules')) {
            depImports[path] = normalizePath(id)
            return {
              path: id,
              external: true, // 表示这是个外部模块 不需要处理
            }
          } else {
            return {
              path: id,
            }
          }
        }
        return { path }
      })

      build.onLoad(
        { filter: htmlTypesRE, namespace: 'html' },
        async ({ path }) => {
          // 需要把html 转成js 才能进行后续的处理

          const html = await fs.readFile(path, 'utf-8')
          let [, src] = html.match(scriptModuleRE)
          let jsContent = `import ${JSON.stringify(src)}`
          return {
            contents: jsContent,
            loader: 'js',
          }
        }
      )
    },
  }
}

module.exports = getScanPlugin
